package com.dianshang.service.impl;

import com.alibaba.dubbo.config.annotation.Service;
import com.dianshang.dao.OrderConfigDao;
import com.dianshang.dao.OrderDao;
import com.dianshang.dao.OrderItemDao;
import com.dianshang.dao.OrderLogDao;
import com.dianshang.entity.PageResult;
import com.dianshang.pojo.order.*;
import com.dianshang.service.order.OrderService;
import com.dianshang.utils.IdWorker;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import tk.mybatis.mapper.entity.Example;

import java.time.LocalDateTime;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
import java.util.Map;

/**
 * @Service(interfaceClass = OrderService.class)
 * 注意！！！这个方法要对两个表进行操作,需要添加事务。
 */
@Service(interfaceClass = OrderService.class)
public class OrderServiceImpl implements OrderService {

    @Autowired
    private OrderDao orderDao;

    @Autowired
    private OrderItemDao orderItemDao;

    @Autowired
    private IdWorker idWorker;

    /**
     * 查询所有
     */
    @Override
    public List<Order> findAll() {
        return orderDao.selectAll();
    }

    /**
     * 发货页面
     * 查询所有+分页(带查询条件)
     * 条件:
     *      发货状态: 没发货
     *      是否删除: 未删除
     *      订单状态: 待发货
     */
    @Override
    public PageResult<Order> findPage(Integer page, Integer size) {
        PageHelper.startPage(page,size);
        Example example = new Example(Order.class);
        Example.Criteria criteria = example.createCriteria();
        criteria.andEqualTo("consignStatus","0"); // 发货状态 1:发货,0:没发货
        criteria.andEqualTo("isDelete","0"); // 是否删除 1:删除,0:未删除
        criteria.andEqualTo("orderStatus","1"); // 订单状态 0:待付款,1:待发货,2:已发货,3:已完成,4:已关闭
        Page<Order> orders = (Page<Order>) orderDao.selectByExample(example);
        return new PageResult<Order>(orders.getTotal(),orders.getResult());
    }

    /**
     * 查询所有+模糊
     * searchMap 查询条件
     */
    @Override
    public List<Order> findList(Map<String, Object> searchMap) {
        Example example = createExample(searchMap);
        return orderDao.selectByExample(example);
    }

    /**
     * 查询所有+分页+模糊
     * searchMap
     * page
     * size
     */
    @Override
    public PageResult<Order> findPage(Map<String, Object> searchMap, Integer page, Integer size) {
        PageHelper.startPage(page,size);
        Example example = createExample(searchMap);
        Page<Order> orders = (Page<Order>) orderDao.selectByExample(example);
        return new PageResult<Order>(orders.getTotal(),orders.getResult());
    }

    /**
     * 查询订单组合
     * id
     */
    @Override
    @Transactional // 事务会覆盖类的事务配置信息
    public OrderDetail findById(String id) {
        // 查询order列表
        Order order = orderDao.selectByPrimaryKey(id);
        // 查询order_item列表
        Example example = new Example(OrderItem.class);
        Example.Criteria criteria = example.createCriteria();
        criteria.andEqualTo("orderId", id);
        List<OrderItem> orderItems = orderItemDao.selectByExample(example);
        // 封装为组合实体类
        OrderDetail orderDetail = new OrderDetail();
        orderDetail.setOrder(order);
        orderDetail.setOrderItem(orderItems);
        return orderDetail;
    }

    /**
     * 新增
     * order
     */
    @Override
    public void add(Order order) {
        orderDao.insert(order);
    }

    /**
     * 修改
     * order
     */
    @Override
    public void update(Order order) {
        orderDao.updateByPrimaryKeySelective(order);
    }

    /**
     * 删除
     * id
     */
    @Override
    public void delete(Integer id) {
        orderDao.deleteByPrimaryKey(id);
    }

    /**
     * 发货
     */
    // 方法一(发货):
    @Override
    public int batchSend(Order order) {
        if (order.getShippingName()==null && order.getShippingCode()==null){
            throw new RuntimeException("请选择合适的物流公司并填写单号");
        }
        order.setOrderStatus("2"); // 订单状态 0:待付款,1:待发货,2:已发货,3:已完成,4:已关闭
        order.setConsignStatus("1"); // 发货状态 1:发货,0:没发货
        order.setConsignTime(new Date()); // 发货时间
        return orderDao.updateByPrimaryKeySelective(order);
    }
    // 方法二(发货):
    /* @Override
    public int batchSend(String id) {
        Order order = orderDao.selectByPrimaryKey(id);
         if (order.getShippingName()==null && order.getShippingCode()==null){
             throw new RuntimeException("请选择合适的物流公司并填写单号");
         }
        order.setOrderStatus("2"); // 订单状态 0:待付款,1:待发货,2:已发货,3:已完成,4:已关闭
        order.setConsignStatus("1"); // 发货状态 1:发货,0:没发货
        order.setConsignTime(new Date()); // 发货时间
        return orderDao.updateByPrimaryKeySelective(order);
    } */
    // 方法三(发货):
    /* @Override
    public int batchSend(Map<String, String> map) {
        String id = map.get("id");
        Order order = orderDao.selectByPrimaryKey(id);
         if (order.getShippingName()==null && order.getShippingCode()==null){
             throw new RuntimeException("请选择合适的物流公司并填写单号");
         }
        order.setOrderStatus("2"); // 订单状态 0:待付款,1:待发货,2:已发货,3:已完成,4:已关闭
        order.setConsignStatus("1"); // 发货状态 1:发货,0:没发货
        order.setConsignTime(new Date()); // 发货时间
        return orderDao.updateByPrimaryKeySelective(order);
    } */

    @Autowired
    private OrderLogDao orderLogDao;

    /**
     * 批量发货
     */
    // 方法一(批量发货):
    @Override
    public void batchSendMore(List<Order> orders) {
        for (Order order : orders) {
            if (order.getShippingName()==null && order.getShippingCode()==null){
                throw new RuntimeException("请选择合适的物流公司并填写单号");
            }
            order.setOrderStatus("2"); // 订单状态 0:待付款,1:待发货,2:已发货,3:已完成,4:已关闭
            order.setConsignStatus("1"); // 发货状态 1:发货,0:没发货
            order.setConsignTime(new Date()); // 发货时间
            orderDao.updateByPrimaryKeySelective(order);
            /**
             * 记录到操作日志
             * 注入IdWorker,生成id
             */
            OrderLog orderLog=new OrderLog();
            orderLog.setId(idWorker.nextId()+"");
            orderLog.setOperater("admin");
            orderLog.setOperateTime(new Date());
            orderLog.setOrderId(order.getId());
            orderLog.setOrderStatus(order.getOrderStatus());
            orderLog.setPayStatus(order.getPayStatus());
            orderLog.setConsignStatus(order.getConsignStatus());
            orderLog.setRemarks("发货");
            orderLogDao.insert(orderLog);
        }
    }
    // 方法二(批量发货):
    /* @Override
    public int batchSendMore(String[] ids) {
        Order order = new Order();
         if (order.getShippingName()==null && order.getShippingCode()==null){
             throw new RuntimeException("请选择合适的物流公司并填写单号");
         }
        order.setOrderStatus("2"); // 订单状态 0:待付款,1:待发货,2:已发货,3:已完成,4:已关闭
        order.setConsignStatus("1"); // 发货状态 1:发货,0:没发货
        order.setConsignTime(new Date()); // 发货时间
        Example example = new Example(Order.class);
        Example.Criteria criteria = example.createCriteria();
        criteria.andIn("id", Arrays.asList(ids));
        return orderDao.updateByExampleSelective(order,example);
         *//**
          * 记录到操作日志
          * 注入IdWorker,生成id
          *//*
         OrderLog orderLog=new OrderLog();
         orderLog.setId(idWorker.nextId()+"");
         orderLog.setOperater("admin");
         orderLog.setOperateTime(new Date());
         orderLog.setOrderId(order.getId());
         orderLog.setOrderStatus(order.getOrderStatus());
         orderLog.setPayStatus(order.getPayStatus());
         orderLog.setConsignStatus(order.getConsignStatus());
         orderLog.setRemarks("发货");
         orderLogDao.insert(orderLog);
    } */

    /**
     * 合并订单: 选择二个订单,进行合并,合并后的实付金额,会落到你选择的第一个订单
     */
    @Override
    @Transactional // 事务会覆盖类的事务配置信息
    public void hebing(String id1, String id2) {
        Order order1 = orderDao.selectByPrimaryKey(id1);
        Order order2 = orderDao.selectByPrimaryKey(id2);

        order1.setPayMoney(order1.getPayMoney()+order2.getPayMoney());

        Example example = new Example(OrderItem.class);
        Example.Criteria criteria = example.createCriteria();
        criteria.andEqualTo("orderId", id2);
        List<OrderItem> orderItems = orderItemDao.selectByExample(example);
        for (OrderItem orderItem : orderItems) {
            orderItem.setOrderId(id1);
            orderItemDao.updateByPrimaryKeySelective(orderItem);
        }

        orderDao.updateByPrimaryKeySelective(order1);
        order2.setIsDelete("1"); // 是否删除 1:删除,0:未删除
        orderDao.updateByPrimaryKeySelective(order2);
    }

    /**
     * 拆分订单: 拆分一个订单后(订单1),又生成一个新订单(订单2)
     */
    @Override
    public void chai(Map<String, String> map) {
        String id = map.get("id");
        String num1 = map.get("num1");
        String num2 = map.get("num2");

        Example example = new Example(OrderItem.class);
        Example.Criteria criteria = example.createCriteria();
        criteria.andEqualTo("orderId", id);
        List<OrderItem> orderItems = orderItemDao.selectByExample(example);
        OrderItem orderItem = orderItems.get(0);
        orderItem.setNum(Integer.valueOf(num1));
        orderItem.setMoney(orderItem.getPrice() * Integer.valueOf(num1));
        orderItemDao.updateByPrimaryKeySelective(orderItem);

        orderItem.setId(idWorker.nextId() + "");
        orderItem.setNum(Integer.valueOf(num2));
        orderItem.setMoney(orderItem.getPrice() * Integer.valueOf(num2));
        orderItemDao.insert(orderItem);
    }

    @Autowired
    private OrderConfigDao orderConfigDao;

    /**
     * 订单超时自动处理
     */
    @Override
    @Transactional // 事务会覆盖类的事务配置信息
    public void orderOutTime() {
        OrderConfig config = orderConfigDao.selectByPrimaryKey(1);
        LocalDateTime localDateTime = LocalDateTime
                .now()
                .minusMinutes(config.getOrderTimeout());

        Example example = new Example(Order.class);
        Example.Criteria criteria = example.createCriteria();
        criteria.andLessThan("createTime",localDateTime); // 订单创建时间
        criteria.andEqualTo("orderStatus","0"); // 订单状态 0:待付款,1:待发货,2:已发货,3:已完成,4:已关闭
        criteria.andEqualTo("isDelete","0"); // 是否删除 1:删除,0:未删除
        List<Order> orders = orderDao.selectByExample(example);
        for(Order order : orders){
            order.setCloseTime(new Date());
            order.setOrderStatus("4"); // 订单状态 0:待付款,1:待发货,2:已发货,3:已完成,4:已关闭
            orderDao.updateByPrimaryKeySelective(order);
            /**
             * 记录到操作日志
             * 注入IdWorker,生成id
             */
            OrderLog orderLog=new OrderLog();
            orderLog.setId(idWorker.nextId()+"");
            orderLog.setOperater("system");
            orderLog.setOperateTime(new Date());
            orderLog.setOrderStatus("4");
            orderLog.setConsignStatus(order.getConsignStatus());
            orderLog.setRemarks("超时订单，系统自动关闭");
            orderLog.setOrderId(order.getId());
            orderLogDao.insert(orderLog);
        }
    }

    /**
     * 构建查询条件
     * searchMap
     */
    private Example createExample(Map<String, Object> searchMap){
        Example example=new Example(Order.class);
        Example.Criteria criteria = example.createCriteria();
        if(searchMap != null){
            // 订单id
            if(searchMap.get("id")!=null && !"".equals(searchMap.get("id"))){
                criteria.andLike("id","%"+searchMap.get("id")+"%");
            }
            // 支付类型，1、在线支付、0 货到付款
            if(searchMap.get("payType")!=null && !"".equals(searchMap.get("payType"))){
                criteria.andLike("payType","%"+searchMap.get("payType")+"%");
            }
            // 物流名称
            if(searchMap.get("shippingName")!=null && !"".equals(searchMap.get("shippingName"))){
                criteria.andLike("shippingName","%"+searchMap.get("shippingName")+"%");
            }
            // 物流单号
            if(searchMap.get("shippingCode")!=null && !"".equals(searchMap.get("shippingCode"))){
                criteria.andLike("shippingCode","%"+searchMap.get("shippingCode")+"%");
            }
            // 用户名称
            if(searchMap.get("username")!=null && !"".equals(searchMap.get("username"))){
                criteria.andLike("username","%"+searchMap.get("username")+"%");
            }
            // 买家留言
            if(searchMap.get("buyerMessage")!=null && !"".equals(searchMap.get("buyerMessage"))){
                criteria.andLike("buyerMessage","%"+searchMap.get("buyerMessage")+"%");
            }
            // 是否评价
            if(searchMap.get("buyerRate")!=null && !"".equals(searchMap.get("buyerRate"))){
                criteria.andLike("buyerRate","%"+searchMap.get("buyerRate")+"%");
            }
            // 收货人
            if(searchMap.get("receiverContact")!=null && !"".equals(searchMap.get("receiverContact"))){
                criteria.andLike("receiverContact","%"+searchMap.get("receiverContact")+"%");
            }
            // 收货人手机
            if(searchMap.get("receiverMobile")!=null && !"".equals(searchMap.get("receiverMobile"))){
                criteria.andLike("receiverMobile","%"+searchMap.get("receiverMobile")+"%");
            }
            // 收货人地址
            if(searchMap.get("receiverAddress")!=null && !"".equals(searchMap.get("receiverAddress"))){
                criteria.andLike("receiverAddress","%"+searchMap.get("receiverAddress")+"%");
            }
            // 订单来源：1:web，2：app，3：微信公众号，4：微信小程序  5 H5手机页面
            if(searchMap.get("sourceType")!=null && !"".equals(searchMap.get("sourceType"))){
                criteria.andLike("sourceType","%"+searchMap.get("sourceType")+"%");
            }
            // 交易流水号
            if(searchMap.get("transactionId")!=null && !"".equals(searchMap.get("transactionId"))){
                criteria.andLike("transactionId","%"+searchMap.get("transactionId")+"%");
            }
            // 订单状态
            if(searchMap.get("orderStatus")!=null && !"".equals(searchMap.get("orderStatus"))){
                criteria.andLike("orderStatus","%"+searchMap.get("orderStatus")+"%");
            }
            // 支付状态
            if(searchMap.get("payStatus")!=null && !"".equals(searchMap.get("payStatus"))){
                criteria.andLike("payStatus","%"+searchMap.get("payStatus")+"%");
            }
            // 发货状态
            if(searchMap.get("consignStatus")!=null && !"".equals(searchMap.get("consignStatus"))){
                criteria.andLike("consignStatus","%"+searchMap.get("consignStatus")+"%");
            }
            // 是否删除
            if(searchMap.get("isDelete")!=null && !"".equals(searchMap.get("isDelete"))){
                criteria.andLike("isDelete","%"+searchMap.get("isDelete")+"%");
            }
            // 数量合计
            if(searchMap.get("totalNum")!=null ){
                criteria.andEqualTo("totalNum",searchMap.get("totalNum"));
            }
            // 金额合计
            if(searchMap.get("totalMoney")!=null ){
                criteria.andEqualTo("totalMoney",searchMap.get("totalMoney"));
            }
            // 优惠金额
            if(searchMap.get("preMoney")!=null ){
                criteria.andEqualTo("preMoney",searchMap.get("preMoney"));
            }
            // 邮费
            if(searchMap.get("postFee")!=null ){
                criteria.andEqualTo("postFee",searchMap.get("postFee"));
            }
            // 实付金额
            if(searchMap.get("payMoney")!=null ){
                criteria.andEqualTo("payMoney",searchMap.get("payMoney"));
            }
        }
        return example;
    }

}